export class HttpRequest {
    /**
     * 创建HTTP请求对象
     * @param httpConfig : Object  HTTP的配置对象，
     *
     * httpConfig 中可配置的字段如下：
     *
     * baseURL : string    基URL
     * method  : string    默认的请求方式
     * publicData : Object | (reqOptions)=>Object  公共的参数 或者是 用来获取公共参数的函数，会对所有请求都追加些参数
     * reqTransforms : [(ReqOptions)=>ReqOptions]  转换请求选项的转换函数数组，用于对reqOptions进行转换，也可以在函数里给数据添加一些公共的参数
     * resTransforms : [(Response,ReqOptions)=>Response]  转换响应的转换函数数组，用于对 response 进行转换；
     * headers  : Object    默认的请求头对象
     * responseType : string         表明服务器返回的数据类型，如：'json','text' 等等
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * mainDataGet  : (responseData:any)=>mainData:any    如果 mainData 设置为 true，当请求成功时，会返回被 mainDataGet 处理过的数据；
     * successPrompt : boolean    是否启用全局的成功提示；
     * promptHandle : (info:data | error,success:boolean)=>Void    请求成功或者失败的回调函数
     * failPrompt  : boolean    是启用用全局的失败提示;
     * showLoading  : boolean    是否启用加载状态指示；默认值为 true
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * startLoadHandle : (loadText:string,reqOptions:ReqOptions,loadingShowCount:number,globalLoadingShowCount:number)=>showCountIncrStep : number | undefined  请求开始的回调函数；返回 加载状态指示显示计数 loadingShowCount 的 增加量；
     * endLoadHandle  : (reqOptions:ReqOptions,loadingShowCount:number,globalLoadingShowCount:number)=>showCountDecrStep : number | undefined   请求结束的回调函数；返回 加载状态指示显示计数 loadingShowCount 的 减少量；
     *
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependentPro : Promise 请求的依赖项，当请求有依赖时，请求会 等到 dependentPro 解决之后触发
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     *
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     *
     *
     */
    constructor({showLoading = true,loadingDelay=0, ...otherConfig}) {

        Object.assign(this, otherConfig);

        this.responseType = otherConfig.findValueForKeyFormats("responseType", this.propFormats);
        this.showLoading = showLoading;
        this.loadingDelay = loadingDelay;

    }


    //显示计数：开始

    /**
     * 全局的 加载状态指示的显示计数
     */
    static loadingShowCount = 0;


    /**
     * 将 全局的 加载状态指示的显示计数 loadingShowCount 增加 step
     * @param step ? : number 默认值:1; 增加的数量；
     * @returns number 增加后的 显示计数 loadingShowCount 值
     */
    static incrLoadingShowCount(step){
        step = step == undefined ? 1 : step;
        return this.loadingShowCount += step;
    }

    /**
     * 将 全局的 加载状态指示的显示计数 loadingShowCount 减少 step
     * @param step ? : number 默认值:1; 减少的数量；
     * @returns number 减少后的 显示计数 loadingShowCount 值
     */
    static decrLoadingShowCount(step){
        step = step == undefined ? 1 : step;
        return this.loadingShowCount -= step;
    }



    /**
     * 加载状态指示的显示计数
     */
    loadingShowCount = 0;

    /**
     * 将 加载状态指示的显示计数 loadingShowCount 增加 step
     * @param step ? : number 默认值:1; 增加的数量；
     * @returns number 增加后的 显示计数 loadingShowCount 值
     */
    incrLoadingShowCount(step){
        step = step == undefined ? 1 : step;
        this.constructor.incrLoadingShowCount(step);
        return this.loadingShowCount += step;
    }

    /**
     * 将 加载状态指示的显示计数 loadingShowCount 减少 step
     * @param step ? : number 默认值:1; 减少的数量；
     * @returns number 减少后的 显示计数 loadingShowCount 值
     */
    decrLoadingShowCount(step){
        step = step == undefined ? 1 : step;
        this.constructor.decrLoadingShowCount(step);
        return this.loadingShowCount -= step;
    }


    //显示计数：结束




    /**
     * 属性的格式列表
     */
    propFormats = [{caseType: "N"}, {caseType: "L"}, {caseType: "U"}, {separator: "-", caseType: "L"}, {
        separator: "-",
        caseType: "U"
    }, {separator: "-", caseType: "N"}];


    /**
     * 有请求体的请求方式列表
     * @type {string[]}
     */
    haveHttpBodyMethods = ["post"];


    set reqTransforms(newValue) {

        if (newValue && !Array.isArray(newValue)) {
            newValue = [newValue];
        }
        this._reqTransforms = newValue;
    }

    get reqTransforms() {
        if (!this._reqTransforms) {
            this._reqTransforms = [];
        }

        return this._reqTransforms;
    }


    set resTransforms(newValue) {

        if (newValue && !Array.isArray(newValue)) {
            newValue = [newValue];
        }
        this._resTransforms = newValue;
    }

    get resTransforms() {
        if (!this._resTransforms) {
            this._resTransforms = [];
        }

        return this._resTransforms;
    }


    // dependentPro 请求依赖的 Promise
    set dependentPro(newValue) {
        if (this._dependentResolve) {
            this._dependentResolve(newValue);
        }

        this._dependentPro = newValue;
    }

    get dependentPro() {
        if (!this._dependentPro) {
            this._dependentPro = new Promise((resolve, reject) => {
                this._dependentResolve = resolve;
            });
        }

        return this._dependentPro;
    }


    set mainDataGet(newValue) {
        this._mainDataGet = newValue;
    }

    get mainDataGet() {
        if (!this._mainDataGet) {
            this._mainDataGet = function (responseData) {
                return responseData;
            };
        }

        return this._mainDataGet;
    }


    /**
     * 请求头的配置对象 headers
     * headers 可配置如下选项：
     * headers.common : Object    配置所有请求公共的请求头字段
     * headers.get : Object    配置 get 请求的请求头字段
     * headers.put : Object    配置 put 请求的请求头字段
     * headers.post : Object    配置 post 请求的请求头字段
     * headers.patch : Object    配置 patch 请求的请求头字段
     * headers.head : Object    配置 head 请求的请求头字段
     * headers.delete : Object    配置 delete 请求的请求头字段
     */
    set headers(newValue) {
        if (newValue) {
            let headers = this.headers;
            Object.keys(newValue).forEach((headerKey) => {
                let methodHeader = headers[headerKey] || {};
                headers[headerKey] = Object.assign(methodHeader, newValue[headerKey]);
            });
            this._headers = headers;
        }
    }

    get headers() {
        if (!this._headers) {
            this._headers = {};
        }
        return this._headers;
    }


    /**
     * 设置 headers
     * @param key : string    headers的键
     * @param value : string   值
     * @param methods ? : Method | [Method]   默认值：common，表示对所有的请求方式都有效； key 和 value 被应用到的请求方式的列表；
     */
    setHeaders(key, value, methods = "common") {
        let headers = this.headers;

        if (!Array.isArray(methods)) {
            methods = [methods];
        }

        methods.forEach(function (method) {

            method = method.toLowerCase();
            methodHeader = headers[method];
            if (!methodHeader) {
                methodHeader = {};
            }

            methodHeader[key] = value;
            headers[method] = methodHeader;

        });


        this.headers = headers;
    }


    /**
     * 获取 相应请求方式的 headers
     * @param method ? : Method   默认值：common，表示获取通用的头；
     */
    getHeaders(method) {
        var headers = this.headers;

        var commonHeader = headers["common"];
        if (method) {
            method = method.toLowerCase();
            var methodHeader = headers[method];

        }

        if (commonHeader || methodHeader) {
            var finalHeader = {...commonHeader, ...methodHeader};
        }

        return finalHeader;
    }


    set authorization(newValue) {
        if (newValue) {
            if (typeof newValue == object) {
                newValue = JSON.stringify(newValue);
            }
            this.setHeaders('Authorization', newValue);
        }
    }


    set contentType(newValue) {
        if (newValue) {
            this.setHeaders('Content-Type', newValue, "post");
        }
    }


    /**
     * 添加公共参数
     * @param reqOptions : ReqOptions
     * @returns ReqOptions
     */
    addPublicData(reqOptions) {
        //  公共参数
        let publicData = this.publicData;

        if  (typeof publicData == "function"){
            publicData = this.publicData(reqOptions);
        }

        if (publicData) {
            publicData = Object.assign({}, publicData);
        } else {
            return reqOptions;
        }

        let {params, data, method = this.method} = reqOptions;

        if (params) {
            params = {...publicData, ...params};
        }


        if (typeof data == "object") {
            if (data.constructor.name == "Object") {
                data = {...publicData, ...data};
            }
        }

        if (!params && !data) {
            if (method && this.haveHttpBodyMethods.includes(method.toLowerCase())) {
                data = publicData;
            } else {
                params = publicData;
            }
        }

        if (params) {
            reqOptions.params = params;
        }

        if (data) {
            reqOptions.data = data;
        }

        return reqOptions;
    }


    /**
     * 发送请求
     * @param reqOptions : Object  请求的选项对象，
     *
     * reqOptions 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * method  : string    请求方式
     * data  : Object    请求的数据，这些数据将被放入请求体中
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * header | headers  : Object    请求头对象
     * responseType : string         表明服务器返回的数据类型，如：'json','text' 等等
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。

     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */


    request(reqOptions) {

        let {dependent = this.dependent, dependResultHandle = this.dependResultHandle} = reqOptions;

        if (dependent) {
            return this.dependentPro.then((dependentResult) => {
                let depReqOptions = dependResultHandle && dependResultHandle(dependentResult, reqOptions);

                if (depReqOptions == false) {
                    return Promise.reject("请求被依赖阻止！")
                } else {
                    depReqOptions = depReqOptions || reqOptions;
                    return this._request(depReqOptions)
                }

            });
        } else {
            return this._request(reqOptions)
        }

    }

    _request(reqOptions) {
        let addPublicOptions = this.addPublicData(reqOptions);

        reqOptions = this.reqTransforms.reduce(function (options, transform) {
            let newOptions = transform(options);
            return newOptions;
        }, addPublicOptions);

      let { urlPath, baseURL = this.baseURL, method = this.method, params, validateHttpStatus = this.validateHttpStatus, validateDataStatus = this.validateDataStatus, successPrompt = this.successPrompt, failPrompt = this.failPrompt, mainData = this.mainData, showLoading = this.showLoading,loadingDelay=this.loadingDelay, loadText = this.loadText, dependent, dependResultHandle, ...otherConfig} = reqOptions;

        
        if (baseURL) {
            urlPath = baseURL + urlPath;
        }

        if (params) {
            urlPath = wx.stringifyUrl({
                href:urlPath,
                addSearchParams:params
            });
        }
        


        let reqConfig = {
            url: urlPath,
            ...otherConfig
        };

        if (method) {
            reqConfig.method = method.toUpperCase();
        }

        let methodHeader = this.getHeaders(method);
        let header = reqOptions.findValueOfKeys(["header", "headers"]);
        if (header || methodHeader) {
            reqConfig.header = {...methodHeader, ...header};
        }

        let responseType = reqOptions.findValueForKeyFormats("responseType", this.propFormats) || this.responseType;
        if (responseType) {
            reqConfig.responseType = responseType;
        }


        if (showLoading && this.startLoadHandle) {
            //mark:显示加载指示器
            var loadingIsStarted = false;
            var performStartLoadHandle = ()=>{
                loadingIsStarted = true;
                var step = this.startLoadHandle(loadText, reqOptions,this.loadingShowCount,this.constructor.loadingShowCount);
                this.incrLoadingShowCount(step);
            };

            if (loadingDelay>0){
                var loadingTimeoutID = setTimeout(performStartLoadHandle,loadingDelay);
            } else{
                performStartLoadHandle();
            }
        }



      let requestTask = null;
        let axiosPromise = new Promise((resolve, reject) => {

            reqConfig.success = (response) => {

                if (validateHttpStatus) {
                    let statusCode = response.statusCode;
                    if (Array.isArray(validateHttpStatus)) {
                        var isValidated = validateHttpStatus.includes(statusCode);
                    } else if (typeof newValue == "function") {
                        isValidated = validateHttpStatus.call(this, statusCode, response, reqOptions);
                    }else {
                        isValidated = statusCode == validateHttpStatus;
                    }

                    if (!isValidated) {
                        reject(response);
                    }
                }

                response = this.resTransforms.reduce(function (res, transform) {
                    let newRes = transform(res, reqOptions);
                    return newRes;
                }, response);

                let respData = response.data;

                if (validateDataStatus && !validateDataStatus(respData,reqOptions)) {
                    reject(respData);
                    return;
                }

                if (successPrompt && this.promptHandle) {
                    // mark: 成功的弹窗提示
                    this.promptHandle(respData, true);
                }


                if (mainData) {
                    respData = this.mainDataGet(respData);
                }

                resolve(respData);

            };

            reqConfig.fail = (error) => {

                if (failPrompt && this.promptHandle) {
                    //mark: 失败的弹窗提示
                    this.promptHandle(error, false);
                }

                let throwData = error.response || error;

                reject(throwData);

            };


            reqConfig.complete = (res) => {
                loadingTimeoutID && clearTimeout(loadingTimeoutID);
                if (loadingIsStarted && this.endLoadHandle) {
                    //mark:关闭加载指示器
                    var step = this.endLoadHandle(reqOptions,this.loadingShowCount,this.constructor.loadingShowCount);
                    this.decrLoadingShowCount(step);
                }
            };

            requestTask = wx.request(reqConfig);
        });

      axiosPromise.requestTask = requestTask;


        return axiosPromise;

    }


    /**
     * 发送get请求
     * @param options : ReqOptions   get请求的选项对象;
     *
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    get(options) {
        options.method = "get";
        return this.request(options);
    }


    /**
     * 发送post请求
     * @param options : ReqOptions
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * data  : Object    请求的数据，这些数据将被放入请求体中
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * contentType  : string    请求头的'Content-Type'字段的值
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     *
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    post(options) {
        let {contentType, ...reqOptions} = options;

        if (contentType) {
            let header = reqOptions.findValueOfKeys(["header", "headers"]);
            reqOptions.header = {...header, 'Content-Type': contentType};
        }

        reqOptions.method = "POST";

        return this.request(reqOptions);
    }


    /**
     * 发送 put 请求
     * @param options : ReqOptions
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * data  : Object    请求的数据，这些数据将被放入请求体中
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * contentType  : string    请求头的'Content-Type'字段的值
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: (status: number,response,reqOptions) => boolean    定义 http返回状态码 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     *
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    put(options) {
        let {contentType, ...reqOptions} = options;

        if (contentType) {
            let header = reqOptions.findValueOfKeys(["header", "headers"]);
            reqOptions.header = {...header, 'Content-Type': contentType};
        }

        reqOptions.method = "put";

        return this.request(reqOptions);
    }


    /**
     * 发送 patch 请求
     * @param options : ReqOptions
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * data  : Object    请求的数据，这些数据将被放入请求体中
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * contentType  : string    请求头的'Content-Type'字段的值
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     *
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    patch(options) {
        let {contentType, ...reqOptions} = options;

        if (contentType) {
            let header = reqOptions.findValueOfKeys(["header", "headers"]);
            reqOptions.header = {...header, 'Content-Type': contentType};
        }

        reqOptions.method = "patch";

        return this.request(reqOptions);
    }


    /**
     * 发送 delete 请求
     * @param options : ReqOptions   get请求的选项对象;
     *
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    delete(options) {
        options.method = "delete";
        return this.request(options);
    }


    /**
     * 发送 head 请求
     * @param options : ReqOptions   get请求的选项对象;
     *
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    head(options) {
        options.method = "head";
        return this.request(options);
    }


    /**
     * 发送 options 请求
     * @param options : ReqOptions   get请求的选项对象;
     *
     *
     * options 中可配置的字段如下：
     *
     * urlPath : string    url路径
     * params  : Object    请求的参数，这些参数将会被序列化放入请求的URL后面
     * header | headers  : Object    请求头对象
     * successPrompt : boolean    是否启用全局的成功提示；
     * failPrompt  : boolean    是启用用全局的失败提示;
     * mainData  : boolean    当请求成功时，是否返回经过 mainDataGet 处理过的数据；
     * showLoading  : boolean    是否启用加载状态指示；
     * loadingDelay  : number    加载状态指示的延时显示时间，单位：毫秒；默认值：0
     * loadText  : string   加载的提示文本
     * dependent : boolean   设置请求是否依赖 dependentPro
     * dependResultHandle : (result,reqOptions)=> HandleResult : ReqOptions || boolean || null || undefined    依赖结果处理器，当请求有依赖时，在 依赖解决之后 请求解决之前 调用该处理器；
     * 注意：
     * - 当 HandleResult 为 false 时，会取消请求；
     * - 当 HandleResult 为 非假值时， 会使用 HandleResult 进行请求；
     * - 当 HandleResult 为 除 false 之外的假值时，会使用 原来的 reqOptions 进行请求；
     * validateHttpStatus ?: number | string | Array<status> | (status: number,response,reqOptions) => boolean     定义 有效的 http返回状态码，可以是有效状态码 或 有效状态码的数组，也可以是返回表示状态码是否有效的布尔值的函数，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * validateDataStatus ?: (responseData: any,reqOptions:ReqOptions) => boolean   定义 后台数据的返回的状态码的 的有效性，如果返回true（或者设置成null/undefined），promise将会resolve；其他的promise将reject。
     * @returns AxiosPromise    请求的 AxiosPromise 对象
     *
     */
    options(options) {
        options.method = "head";
        return this.request(options);
    }


}


export default HttpRequest;
